﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using CommonControllers.ConfigsService;
using System.Text.RegularExpressions;

namespace CommonControllers
{
    public class CommonControllerBase
    {
        public CommonControllerBase()
        {
        }
        public static void AddCache(string key, object data)
        {
            if (Cache == null)
            {
                InitCache();
            }
            Cache.Set(key, data, CacheTimeOut);
        }
        protected static int CacheTimeOut = -1;
        private static ICacheManager _Cache;
        public static ICacheManager Cache
        {
            get
            {
                return _Cache;
            }
        }
        public static void InitCache()
        {
            _Cache = new CacheManager();
        }
        public void AddIndexToTable(DataTable tblData)
        {
            if (tblData == null) return;
            if (tblData.Columns.Contains("STT"))
            {
                this.ResetTableIndex(tblData);
            }
            else
            {
                tblData.Columns.Add("STT", typeof(int));
                ResetTableIndex(tblData);
            }
        }
        public void ResetTableIndex(DataTable tblData)
        {
            if (!tblData.Columns.Contains("STT")) return;
            for (int i = 0; i < tblData.Rows.Count; i++)
            {
                tblData.Rows[i]["STT"] = i + 1;
            }
        }
        public decimal ConvertNumber(object oNumber)
        {
            decimal n = 0;
            if (oNumber != null) decimal.TryParse(oNumber.ToString(), out n);
            return n;
        }
        public int ConvertInt(object oNumber)
        {
            int n = 0;
            if (oNumber != null) int.TryParse(oNumber.ToString(), out n);
            return n;
        }
        public double ConvertDouble(object oNumber)
        {
            double n = 0;
            if (oNumber != null) double.TryParse(oNumber.ToString(), out n);
            return n;
        }
        public double ConvertLong(object oNumber)
        {
            Int64 n = 0;
            if (oNumber != null) Int64.TryParse(oNumber.ToString(), out n);
            return n;
        }
        public byte ConvertByte(object oNumber)
        {
            byte n = 0;
            byte.TryParse(oNumber.ToString(), out n);
            return n;
        }
        public bool ConvertBool(object oBool)
        {
            if (oBool == null) return false;
            bool result = false;
            try
            {
                result = Convert.ToBoolean(oBool);
            }
            catch
            {
            }
            return result;
        }
        public DateTime ConvertDateTime(object oDate)
        {
            if (oDate == null) return DateTime.Now;
            DateTime result = DateTime.Now;
            try
            {
                result = Convert.ToDateTime(oDate);
            }
            catch
            {
            }
            return result;
        }
        public static void AddConfig(string ConfigName, object Value)
        {
            string val = Value.ToString();
            if (Value.GetType().Equals(typeof(DateTime)))
            {
                val = ((DateTime)Value).ToString("dd/MM/yyyy HH:mm:ss");
            }
            ConfigsServiceClient dao = new ConfigsServiceClient();
            ConfigsEntity configsEntity = dao.SelectOne(ConfigName);
            if (configsEntity != null)
            {
                if (!configsEntity.IsNullConfigValue)
                {
                    dao.UpdateConfigValue(val,ConfigName);
                    return;
                }
            }
            configsEntity = new ConfigsEntity();
            configsEntity.ConfigName = ConfigName;
            configsEntity.ConfigValue = val;
            dao.Save(configsEntity);
        }
        public static void AddConfigList(string ConfigName, List<string> listValues)
        {
            AddConfig(ConfigName, string.Join("$#$", listValues.ToArray()));
        }
        public static void AddConfigDictionary(string ConfigName, Dictionary<string, string> listValues)
        {
            List<string> ls = new List<string>();
            foreach (KeyValuePair<string, string> pair in listValues)
            {
                ls.Add(pair.Key + "=" + pair.Value);
            }
            AddConfigList(ConfigName, ls);
        }
        public static string GetStringConfig(string ConfigName)
        {
            ConfigsServiceClient dao = new ConfigsServiceClient();
            ConfigsEntity oConfigs = dao.SelectOne(ConfigName);
            if (oConfigs != null)
            {
                if (!oConfigs.IsNullConfigValue)
                {
                    return oConfigs.ConfigValue;
                }
            }
            return "";
        }
        public static int GetIntConfig(string ConfigName)
        {
            string val = GetStringConfig(ConfigName);
            if (val == "") return 0;
            return (int)eTMS.Commons.Common.ConvertNumber(val);
        }
        public static double GetDoubleConfig(string ConfigName)
        {
            string val = GetStringConfig(ConfigName);
            if (val == "") return 0;
            return (double)eTMS.Commons.Common.ConvertNumber(val);
        }
        public static DateTime GetDateTimeConfig(string ConfigName)
        {
            string val = GetStringConfig(ConfigName);
            if (val == "") return DateTime.Now;
            return DateTime.ParseExact(val, "dd/MM/yyyy HH:mm:ss", null);
        }
        public static List<string> GetListConfig(string ConfigName)
        {
            string val = GetStringConfig(ConfigName);
            if (val == "") return new List<string>();
            return new List<string>(val.Split("$#$".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
        }
        public static Dictionary<string, string> GetDictionaryConfig(string ConfigName)
        {
            string val = GetStringConfig(ConfigName);
            if (val == "") return new Dictionary<string, string>();
            List<string> ls = new List<string>(val.Split("$#$".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            foreach (string s in ls)
            {
                if (s.IndexOf("=") > 0)
                {
                    string[] arrays = s.Split('=');
                    if (!dictionary.ContainsKey(arrays[0]))
                    {
                        dictionary.Add(arrays[0], arrays[1]);
                    }
                }
            }
            return dictionary;
        }
        public static string[] SplitName(string HoTen)
        {
            while (HoTen.IndexOf("  ") >= 0)
                HoTen = HoTen.Replace("  ", " ");
            HoTen = HoTen.Trim();
            int index = HoTen.LastIndexOf(" ");
            string[] arrays = new string[2];
            if (index > 0)
            {
                arrays[0] = HoTen.Substring(0, index);
                arrays[1] = HoTen.Substring(index + 1);
            }
            else
            {
                arrays[0] = "";
                arrays[1] = HoTen;
            }
            return arrays;
        }
        public static DataTable SortByLastName(string colHoTen, string colHo, string colTen, DataTable tblData)
        {
            if (!tblData.Columns.Contains(colHoTen))
            {
                return tblData;
            }
            if (!tblData.Columns.Contains(colHo))
            {
                tblData.Columns.Add(colHo);
            }
            if (!tblData.Columns.Contains(colTen))
            {
                tblData.Columns.Add(colTen);
            }
            foreach (DataRow r in tblData.Rows)
            {
                string[] arrays = SplitName(r[colHoTen].ToString());
                r[colHo] = arrays[0];
                r[colTen] = arrays[1];
            }
            tblData.DefaultView.Sort = colTen + " ASC";
            return tblData.DefaultView.ToTable();
        }
        public static bool SendSMS(string phonenumber,string message)
        {
            SMSService.SMSServiceClient smsService = new CommonControllers.SMSService.SMSServiceClient();
            return smsService.SendSMSMessage(phonenumber, message);
        }
        public static bool SendSMS(List<string> phonenumbers, string message)
        {
            List<SMSService.SenderContext> ls = new List<CommonControllers.SMSService.SenderContext>();
            foreach (string st in phonenumbers)
            {
                SMSService.SenderContext sNum = new CommonControllers.SMSService.SenderContext();
                sNum.Number = st;
                sNum.Context = message;
                ls.Add(sNum);
            }
            SMSService.SMSServiceClient smsService = new CommonControllers.SMSService.SMSServiceClient();
           return smsService.SendListSMSMessage(ls.ToArray());
      
        }
    }
    /// <summary>
    /// Represents a StaticCache
    /// </summary>
    public class CacheManager : ICacheManager
    {
        private Dictionary<string, object> _context;
        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="context">Context</param>
        public CacheManager()
        {
            this._context = new Dictionary<string, object>();
        }
        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="key">The key of the value to get.</param>
        /// <returns>The value associated with the specified key.</returns>
        public T Get<T>(string key)
        {
            if (!this._context.ContainsKey(key))
                return default(T);
            return (T)_context[key];
        }
        /// <summary>
        /// Adds the specified key and object to the cache.
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="data">Data</param>
        /// <param name="cacheTime">Cache time</param>
        public void Set(string key, object data, int cacheTime)
        {
            if (this._context.ContainsKey(key))
            {
                this._context[key] = data;
            }
            else
            {
                this._context.Add(key, data);
            }
        }
        /// <summary>
        /// Gets a value indicating whether the value associated with the specified key is cached
        /// </summary>
        /// <param name="key">key</param>
        /// <returns>Result</returns>
        public bool IsSet(string key)
        {
            if (_context == null)
                return false;
            return (_context[key] != null);
        }
        /// <summary>
        /// Removes the value with the specified key from the cache
        /// </summary>
        /// <param name="key">/key</param>
        public void Remove(string key)
        {
            if (_context == null)
                return;
            _context.Remove(key);
        }
        /// <summary>
        /// Removes items by pattern
        /// </summary>
        /// <param name="pattern">pattern</param>
        public void RemoveByPattern(string pattern)
        {
            if (_context == null)
                return;
            var enumerator = _context.GetEnumerator();
            var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
            var keysToRemove = new List<String>();
            while (enumerator.MoveNext())
            {
                if (regex.IsMatch(enumerator.Current.Key.ToString()))
                {
                    keysToRemove.Add(enumerator.Current.Key.ToString());
                }
            }
            foreach (string key in keysToRemove)
            {
                _context.Remove(key);
            }
        }
        /// <summary>
        /// Clear all cache data
        /// </summary>
        public void Clear()
        {
            if (_context == null)
                return;
            var enumerator = _context.GetEnumerator();
            var keysToRemove = new List<String>();
            while (enumerator.MoveNext())
            {
                keysToRemove.Add(enumerator.Current.Key.ToString());
            }
            foreach (string key in keysToRemove)
            {
                _context.Remove(key);
            }
        }
    }
    public interface ICacheManager
    {
        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="key">The key of the value to get.</param>
        /// <returns>The value associated with the specified key.</returns>
        T Get<T>(string key);
        /// <summary>
        /// Adds the specified key and object to the cache.
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="data">Data</param>
        /// <param name="cacheTime">Cache time</param>
        void Set(string key, object data, int cacheTime);
        /// <summary>
        /// Gets a value indicating whether the value associated with the specified key is cached
        /// </summary>
        /// <param name="key">key</param>
        /// <returns>Result</returns>
        bool IsSet(string key);
        /// <summary>
        /// Removes the value with the specified key from the cache
        /// </summary>
        /// <param name="key">/key</param>
        void Remove(string key);
        /// <summary>
        /// Removes items by pattern
        /// </summary>
        /// <param name="pattern">pattern</param>
        void RemoveByPattern(string pattern);
        /// <summary>
        /// Clear all cache data
        /// </summary>
        void Clear();
    }

}
